package com.ljm.security.core;

import org.springframework.context.annotation.Primary;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @author: ChenHuaMing
 * @Date: 2020/6/10 17:45
 * @Description: 登录逻辑验证器
 */
@Component
@Primary
public class CustomAuthenticationProvider implements AuthenticationProvider {
    @Resource
    private UserDetailsService userDetailsService;
    @Resource
    private PasswordEncoder passwordEncoder;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // 获取表单输入中返回的用户名
        String userName = authentication.getPrincipal().toString();
        // 获取表单中输入的密码
        String password = authentication.getCredentials().toString();
        //获取用户
        UserDetails userDetail = userDetailsService.loadUserByUsername(userName);
        //判断账号是否禁用
        if(userDetail.isEnabled()){
            throw new DisabledException("账号已禁用,请联系管理员");
        }
        //判断账号是否过期
        if(!userDetail.isAccountNonExpired()){
            throw new AccountExpiredException("账号已过期,请续期");
        }
        //判断账号是否锁定
        if(!userDetail.isAccountNonLocked()){
            throw new LockedException("账号已被锁定,请稍后重试");
        }
        //判断密码是否过期
        if(!userDetail.isCredentialsNonExpired()){
            throw new CredentialsExpiredException("密码已过期,请修改密码");
        }
        //检查密码
        if(!passwordEncoder.matches(password,userDetail.getPassword())){
            throw new BadCredentialsException("密码不正确,请重新输入");
        }

        // 构建返回的用户登录成功的token
        return new UsernamePasswordAuthenticationToken(userName, userDetail.getPassword(), userDetail.getAuthorities());
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }
}
